masterofmagicfandomcom-20200216-history
Talk:Rampaging Monster/@comment-1333593-20171028064124
(I will edit this information into the article as time allows) Short version: *criteria is 50-(Difficulty*5) <= cumulative rampage variable *rampage treshold then is 50, 45, 40, 35, 30 *per-turn increment is Random(Difficulty+1) (1-5) *average increment is 1, 1.5, 2, 2.5, 3 *mean time between is 50, 30, 20, 14, 10 turns *accumulator is reset before turn 50 is checked *base budget: (Random(Difficulty+1) + Random(Difficulty+1)) * Turn_Number / 5 *monster selector quits if budget is under 25 *otherwise 2000 tries of Random(47)+150 to pick creatures *raider generator can also modify rampage accumulator (adds +15 if Raider generation failed despite there being at least one Neutral Town) *(no such thing as monsters always spawn on turn 50) Long Version: Rampaging Monster Function (W $F3092): *Setup ::set ValidLairs to 0; ::for every LairIndex do: :::if Intact AND HasInitialPrimary AND NOT LifeRealm then inc(ValidLairs); ::if ValidLairs = 0 then Return (no monsters); *Rampage Accumulator ::Add Random(Difficulty + 1) to the Rampage Accumulator; ::Set Rampage Treshold to 50 - (Difficulty * 5''); :::::::(Both values are moddable, WORD, W $F3118, and W $F3113, in that order) ::if Rampage Accumulator < Rampage Treshold then Return (no monsters); ::set Rampage Accumulator to '''0; :::::::(WORD, W $F3128) ::if CurrentTurn < '''''50 then Return (no monsters); :::::::(BYTE, W $F312E) ::set Tries to 0; SelectedLair to -1; *Lair Selector ::if Tries >= 1000 OR NOT (SelectedLair = -1) then jump to Budget; :::::::(WORD, W $F32AF, see also below, as it won't work by itself) ::set LairIndex to Random(102) - 1; ::if NOT (Intact AND HasInitialPrimary AND NOT LifeRealm) then do: :::inc(Tries) and jump to Lair Selector; :::::::(Life creatures can be enabled by changing both W $F30E9 and W $F319D BYTEs to $15) ::for every CityIndex do: :::if NOT (SelectedLair = -1) then jump to Budget; (exit the loop if a site is found) :::if City is Neutral or not on same plane as Lair, then next CityIndex; :::if City shares landmass with Lair, then set SelectedLair to LairIndex; (site picked here) ::inc(Tries) and jump to Lair Selector; *Budget ::if Random(3) > 1 then do: :::if NOT (Human_Player_Fortress_Plane = Lair Plane) then jump to Lair Selector; :::(note: I have no idea where this was supposed to jump to do anything. As it is now, it just gets straight back to Budget because a lair is already picked. If it jumped a single instruction further back, it would reset SelectedLair, which may have been the original intention.) ::if NOT (Tries < 1000) then Return (no monsters); :::::::(WORD, W $F32E9, see also above, as it won't work by itself) ::set AI_Turf to 0; ::if NOT (Human_Player_Fortress_Landmass = Lair Landmass) then do: :::for every AI_Player do: ::::if Fortress_Landmass = Lair Landmass then set AI_Turf to 1; :::::::(note: changing the AI_Turf mechanic requires swapping jump instructions, could be set to affect any player, or no players, but is a bit more complicated than swapping immediate values.) ::if Lair has no Primary Monsters then Return (no monsters); ::set Rampage Race to Primary Monster Race; ::if Rampage Race is not a Realm ($0F or below) then set Rampage Race to Death; ::if all surrounding Land tiles are occupied then Return (no monsters); (this can be by units, towns, or other lairs) ::set MonsterBudget to (Random(Difficulty + 1) + Random(Difficulty + 1)) * CurrentTurn / 5''; :::::::(WORD, W $F3488; Diff+1 unfortunately uses a single-byte opcode) ::if AI_Turf = 1 then divide MonsterBudget by 2; ::call Monster Generator (passing MonsterBudget and Rampage Race); (this returns a monster count) ::if MonsterCount > 0 call CreateUnit for each; (this does what one would expect) ::Return; '''Monster Generator Function (W $F086F): ::set Tries and Monster_Count to 0; ::while Tries < '''''2000 AND Budget >= 25 do: :::::::(WORD W $F08FB, BYTE W $F08F5) :::set MonsterIndex to (Random(47) + 150); :::if (Race = Rampage_Realm) AND (Cost <= Budget) AND NOT (Transport > 0) AND (Monster_Count < 9) then ::::add monster to rampaging group, inc(Monster_Count), reduce Budget by Cost; :::inc(Tries);